package com.zy.explore.idempotent.application.service;

import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.StrUtil;
import com.zy.explore.idempotent.infrastructure.constant.ProjectConstant;
import com.zy.explore.idempotent.infrastructure.exception.MessageCode;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.UUID;

/**
 * description 幂等Token服务类
 *
 * @author 🇨🇳中国印🇨🇳
 * @date 2021年07月06日 20:29
 */
@Service
public class TokenService {

    private static final String TOKEN_PREFIX = ProjectConstant.IDEMPOTENT_TOKEN_PREFIX + ":";

    @Resource
    private RedisService redisService;

    /**
     * 创建token
     *
     * @return
     */
    public String createToken() {
        String str = UUID.randomUUID().toString().replace("-", "");
        StrBuilder token = new StrBuilder();
        try {
            token.append(str);
            redisService.setIfAbsent(TOKEN_PREFIX + token, token.toString(), ProjectConstant.IDEMPOTENT_TIME_RANGE);
            boolean notEmpty = StrUtil.isNotEmpty(token.toString());
            if (notEmpty) {
                return token.toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 检验token
     *
     * @param request 请求对象
     * @return
     */
    public boolean checkToken(HttpServletRequest request) {
        String token = request.getHeader(ProjectConstant.IDEMPOTENT_TOKEN_PREFIX);
        if (StrUtil.isBlank(token)) {
            // header中不存在token
            token = request.getParameter(ProjectConstant.IDEMPOTENT_TOKEN_PREFIX);
            if (StrUtil.isBlank(token)) {
                // parameter中也不存在token
                throw MessageCode.IDEMPOTENT_TOKEN_NOT_EXIST_ERROR.toException();
            }
        }
        if (!redisService.setIfAbsent(TOKEN_PREFIX + token, token, ProjectConstant.IDEMPOTENT_TIME_RANGE)) {
            throw MessageCode.REPEAT_OPERATE_ERROR.toException();
        }
        return true;
    }

}
